﻿// 开发者:micropu
// 公司:佛山远钧智慧科技有限公司

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.ChannelsECLogisticsEWaybillAccountGetResponse.Types.Account.Types;

namespace Admin.NET.Application;
public static class YangChengSync
{
    public static async void  Startup()
    {
        string serverAddress = "121.9.243.235"; // 服务器地址
        int serverPort = 9883; // 服务器端口
        string password = "123456"; // 密码

        System.Net.Sockets.TcpClient client1 = new System.Net.Sockets.TcpClient(serverAddress, serverPort);
        System.Net.Sockets.TcpClient client2 = new System.Net.Sockets.TcpClient(serverAddress, serverPort);
        System.Net.Sockets.TcpClient client3 = new System.Net.Sockets.TcpClient(serverAddress, serverPort);

        while (true)
        {
            // ----------------------------执行你的任务
            Console.WriteLine($"client1任务执行时间: {DateTime.Now}");
            NetworkStream stream1 = client1.GetStream();
            string message1 = BuildHJ212Message("Y2020075726008", password);
            // 将消息转换为字节数组
            byte[] data1 = Encoding.ASCII.GetBytes(message1 + "\r\n");

            // 发送数据
            stream1.Write(data1, 0, data1.Length);
            Console.WriteLine("数据已发送: " + message1);

            // 读取服务器响应
            byte[] responseData1 = new byte[256];
            int bytes1 = stream1.Read(responseData1, 0, responseData1.Length);
            string response1 = Encoding.ASCII.GetString(responseData1, 0, bytes1);
            Console.WriteLine("服务器响应: " + response1);


            // -----------------------------执行你的任务
            Console.WriteLine($"client2任务执行时间: {DateTime.Now}");
            NetworkStream stream2 = client2.GetStream();
            string message2 = BuildHJ212Message("YS20221128014", password);
            // 将消息转换为字节数组
            byte[] data2 = Encoding.ASCII.GetBytes(message2 + "\r\n");

            // 发送数据
            stream2.Write(data2, 0, data2.Length);
            Console.WriteLine("数据已发送: " + message2);

            // 读取服务器响应
            byte[] responseData2 = new byte[256];
            int bytes2 = stream2.Read(responseData2, 0, responseData2.Length);
            string response2 = Encoding.ASCII.GetString(responseData2, 0, bytes2);
            Console.WriteLine("服务器响应: " + response2);


            // -----------------------------执行你的任务
            Console.WriteLine($"client3任务执行时间: {DateTime.Now}");
            NetworkStream stream3 = client3.GetStream();
            string message3 = BuildHJ212Message("Y2020075723521", password);
            // 将消息转换为字节数组
            byte[] data3 = Encoding.ASCII.GetBytes(message3 + "\r\n");

            // 发送数据
            stream3.Write(data3, 0, data3.Length);
            Console.WriteLine("数据已发送: " + message3);

            // 读取服务器响应
            byte[] responseData3 = new byte[256];
            int bytes3 = stream3.Read(responseData3, 0, responseData3.Length);
            string response3 = Encoding.ASCII.GetString(responseData3, 0, bytes3);
            Console.WriteLine("服务器响应: " + response3);

            // 等待 1 分钟 (60000 毫秒)
            await Task.Delay(TimeSpan.FromMinutes(1));
        }

    }

    static string BuildHJ212Message(string deviceNumber, string password)
    {
        // string qn       = DateTime.Now.ToString("yyyyMMddHHmmssfff"); // 时间戳
        string qn = DateTime.Now.ToString("yyyyMMddHHmmss") + "000"; // 时间戳
        string dataTime = DateTime.Now.ToString("yyyyMMddHHmmss"); // 数据时间

        //TSP(全尘)实时值103-Rtd 21.6
        //PM2.5实时值925-Rtd=16.40
        //PM10实时值 107-Rtd=19.30
        //噪音 B03-Rtd=64.90

        Random random = new Random();

        // TSP (全尘) 实时值 103-Rtd
        double tspRtd = Math.Round(random.NextDouble() * 10 + 10, 2);  // 生成一个0到100之间的随机数，保留2位小数
        //Console.WriteLine($"TSP(全尘)实时值103-Rtd={tspRtd}");

        // PM2.5 实时值 925-Rtd
        double pm25Rtd = Math.Round(random.NextDouble() * 5 + 5, 2);  // 生成一个0到50之间的随机数，保留2位小数
        //Console.WriteLine($"PM2.5实时值925-Rtd={pm25Rtd}");

        // PM10 实时值 107-Rtd
        double pm10Rtd = Math.Round(random.NextDouble() * 5 + 10, 2);  // 生成一个0到50之间的随机数，保留2位小数
        //Console.WriteLine($"PM10实时值107-Rtd={pm10Rtd}");

        // 噪音 B03-Rtd
        double noiseRtd = Math.Round(random.NextDouble() * 30 + 30, 2);  // 生成一个30到130之间的随机数，保留2位小数
        //Console.WriteLine($"噪音B03-Rtd={noiseRtd}");

        // 构建 CP 部分
        string cp = $"DataTime={dataTime};" +
                    $"925-Rtd={pm25Rtd},925-Flag=N;" +
                    $"107-Rtd={pm10Rtd},107-Flag=N;" +
                    $"103-Rtd={tspRtd},103-Flag=N;" +
                    $"B03-Rtd={noiseRtd},B03-Flag=N;" +
                    "126-Rtd=35.70,126-Flag=N;" +
                    "128-Rtd=60.70,128-Flag=N;" +
                    "129-Rtd=0.00,129-Flag=N;" +
                    "130-Rtd=15,130-Flag=N;" +
                    "127-Rtd=0,127-Flag=N&&";

        // 组装消息主体
        //string messageContent = $"ST=22;CN=2011;QN={qn};PW={password};MN={deviceNumber};CP=&&{cp}&&";
        string messageContent = $"QN={qn};ST=22;CN=2011;PW=123456;MN={deviceNumber};Flag=5;CP=&&{cp}";


        // 计算消息的字节长度
        int length = messageContent.Length; // 加上“##”和消息长度字段及结束符"1B00"的字节数

        // 计算校验码
        string checksum = CalculateChecksum(messageContent);

        // 构建完整的消息，包含校验码和结束标志“1B00”
        //string message = $"##{length:D4}{messageContent}{checksum}1B00";
        string message = $"##{length:D4}{messageContent}{checksum}";

        return message;
    }

    public static string CalculateChecksum(string input)
    {
        ushort crc = 0xFFFF; // 初始值  

        foreach (char c in input)
        {
            crc ^= (byte)c; // 将字符转换为字节并与 CRC 进行异或  

            for (int i = 0; i < 8; i++)
            {
                // 检查最低位  
                if ((crc & 0x0001) == 1)
                {
                    crc = (ushort)((crc >> 1) ^ 0xA001); // 右移并与多项式进行异或  
                }
                else
                {
                    crc >>= 1; // 仅右移  
                }
            }
        }

        // 转换为四位十六进制字符串  
        return crc.ToString("X4").ToUpper(); // 返回四位十六进制字符串  
    }
}
